﻿(function($) {
    /// <summary>Regular Expression Library</summary>
    $.Validators.RegularExpression = { Email: /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/ };
    /// <summary>List of control that validate</summary>
    $.Validators.GroupValidators = {};
    /// <summary>Script Version</summary>
    Version: '1.1';

    $.Validators.Functions = {
        /// <summary>Return value that valuate</summary>
        /// <param name="idControl">Code of control</param>
        /// <returns>value into control</returns>
        GetValueThatValidate: function(idControl) {
            var $control = $('#' + idControl);
            var value = '';

            if ($control.mask) {
                value = $control.getValueWithOutMask();
            } else {
                value = $control.val();
            }

            return value;
        },
        /// <summary>Check if client insert value</summary>
        /// <param name="idControl">code of control</param>
        /// <returns>Indicates if client isert data</returns>
        ValidateRequired: function(idControl) {
            var value = $.Validators.Functions.GetValueThatValidate(idControl);
            return !(value == '' || value == undefined || value == null);
        },
        /// <summary>Validate length of data</summar>
        /// <param name="idControl">code of control</param>
        /// <param name="min">Minimun lenght</param>
        /// <param name="max">Maximun length</param>
        /// <returns>Indicates if correct length</returns>
        ValidateLength: function(idControl, min, max) {
            var value = $.Validators.Functions.GetValueThatValidate(idControl);
            var length = value.length;
            return $.Validators.Functions.CheckRange(length, min, max);
        },
        /// <summary>Check if data is content into range</summary>
        /// <param name="idControl">code of control</param>
        /// <param name="min">Start range value</param>
        /// <param name="max">End range value</param>
        /// <param name="t">Type of data</param>
        /// <returns>Indicates if value is content into range</returns>
        ValidateRange: function(idControl, min, max, t) {
            var value = $.Validators.Functions.GetValueThatValidate(idControl);
            var result = true;
            switch (t) {
                case $.Validators.VarType.Integer:
                    {
                        var n = parseInt(value);

                        if (isNaN(n)) {
                            result = false;
                        } else {
                            result = $.Validators.Functions.CheckRange(n, min, max);
                        }

                        break;
                    }
                case $.Validators.VarType.Float:
                    {
                        var f = parseFloat(value);

                        if (isNaN(f)) {
                            result = false;
                        } else {
                            result = $.Validators.Functions.CheckRange(f, min, max);
                        }

                        break;
                    }
                case $.Validators.VarType.Date:
                    {
                        break;
                    }
            }

            return result;
        },
        /// <summary>Compare value that insert client</summary>
        /// <param name="idControl">code of control</param>
        /// <param name="value">Value that compare</param>
        /// <param name"cmpType">Type of comparete operation</param>
        /// <returns>Indicates if comparation is correct</param>
        ValidateCompare: function(idControl, value, cmpType) {
            var valueControl = $.Validators.Functions.GetValueThatValidate(idControl);
            var result = true;

            if (cmpType == $.Validators.CompareOperator.Equals) {
                result = valueControl == value;
            } else {
                result = valueControl != value;
            }

            return result;
        },
        /// <summary>Validate client data with regular expression</summary>
        /// <param name="idControl">code of control</param>
        /// <param name="regex">Regular expression</param>
        /// <returns>indicates if data is correct</returns>
        ValidateRegex: function(idControl, regex) {
            var value = $.Validators.Functions.GetValueThatValidate(idControl);
            var result = true;

            if ($.Validators.Functions.ValidateRequired(idControl)) {
                var r = new RegExp(regex);
                result = r.test(value);
            }

            return result;
        },
        /// <summary>Check if data is context into rage</summary>
        /// <param name="value">value that check</param>
        /// <param name="min">Start Range</param>
        /// <param name="max">End Range</param>
        /// <returns>Indicates if data is content into range</returns>
        CheckRange: function(value, min, max) {
            var result = true;

            if (min != null) {
                if (value < min) {
                    result = false;
                }
            }

            if (max != null) {
                if (value > max) {
                    result = false;
                }
            }

            return result;
        },
        /// <summary>Add control to list of validation</summary>
        /// <param name="groupName">Name of validation group</param>
        /// <param name="type">Type of validation</param>
        /// <param name="idControl">code of control</param>
        /// <param name="attributes">
        ///     clientNotValid: function that call when data is not valid
        ///     clientValid: function that call when data is valid
        ///     cssClass: name of class for control, that contain not valid data
        ///     min: Start Range
        ///     max: End Range
        ///     regex: Regular Expression
        ///     value: data that compare
        ///     cmpIDControl: code of control that compare data
        ///     cmpOp: Compare Type
        ///     extraAlert: extra alert
        /// </param>
        AddValidator: function(groupName, type, idControl, attributes) {
            var validator = new Object();

            validator.type = type;
            validator.idControl = idControl;

            if (attributes.clientNotValid) {
                validator.clientNotValid = attributes.clientNotValid;
            }

            if (attributes.clientValid) {
                validator.clientValid = attributes.clientValid;
            }

            if (attributes.cssClass) {
                validator.cssClass = attributes.cssClass;
            }

            if (attributes.extraAlert != null) {
                validator.extraAlert = attributes.extraAlert;

                if (attributes.extraCss) {
                    validator.extraCss = attributes.extraCss;
                }
            }

            switch (type) {
                case $.Validators.Types.Length:
                    {
                        validator.min = (attributes.min || attributes.min == 0) ? attributes.min : null;
                        validator.max = (attributes.max || attributes.max == 0) ? attributes.max : null;
                        break;
                    }
                case $.Validators.Types.Compare:
                    {
                        if (attributes.value) {
                            validator.value = attributes.value;
                        } else {
                            validator.cmpIDControl = attributes.cmpIDControl;
                        }
                        validator.cmpOp = attributes.cmpOp;
                        break;
                    }
                case $.Validators.Types.Range:
                    {
                        validator.min = (attributes.min || attributes.min == 0) ? attributes.min : null;
                        validator.max = (attributes.max || attributes.max == 0) ? attributes.max : null;

                        validator.varType = attributes.varType;
                        break;
                    }
                case $.Validators.Types.RegularExpression:
                    {
                        validator.regex = attributes.regex;
                        break;
                    }
            }

            if (!$.Validators.GroupValidators[groupName]) {
                $.Validators.GroupValidators[groupName] = new Array();
            }

            $.Validators.GroupValidators[groupName].push(validator);
        },
        /// <summary>Remove control from list validation</summary>
        /// <param name="idControl">Code of control</param>
        RemoveValidator: function(idControl) {
            var id = -1;
            $.each($.Validators.GroupValidators[groupName], function(i) {
                var validator = $.Validators.GroupValidators[groupName][i];

                if (validator.idControl == idControl) {
                    id = i;
                    return;
                }
            });

            if (id != -1) {
                $.Validators.GroupValidators[groupName] = $.Validators.GroupValidators[groupName].Remove(id, id);
            }
        },
        /// <summary>Execute method for alert client that data is not valid</summary>
        /// <param name="validator">
        ///     cssClass: class for not valid control
        ///     clientNotValid: fuction that call
        /// </param>
        AddNotValid: function(validator) {
            var $control = $('#' + validator.idControl);

            if (validator.cssClass) {
                $control.addClass(validator.cssClass);
            }

            if (validator.clientNotValid) {
                validator.clientNotValid(validator.idControl);
            }

            if (validator.extraAlert != null) {
                if (validator.extraAlert == $.Validators.ExtraAlert.Asterix) {
                    var $sp = $('#atx' + validator.idControl);

                    if ($sp.length == 0) {
                        $sp = $.create('span', { id: 'atx' + validator.idControl, title: validator.error }).html('*');

                        if (validator.extraCss) {
                            $sp.addClass(validator.extraCss);
                        }

                        $control.after($sp);
                    }
                } else if (validator.extraAlert == $.Validators.ExtraAlert.ToolTip) {
                    $control.attr('title', validator.error);
                } else {
                    var $pop = $('#pop' + validator.idControl);

                    if ($pop.length == 0) {
                        $pop = $.create('div', { id: 'pop' + validator.idControl }).html(validator.error);

                        if (validator.extraCss) {
                            $pop.addClass(validator.extraCss);
                        }

                        var position = $control.position();

                        $('body').append($pop.setAbsolutePosition({ Top: position.top + $control.height(), Left: position.left + $control.width() }));
                    }
                }
            }
        },
        /// <summary>Execute method for alert client that data is valid</summary>
        /// <param name="validator">
        ///     cssClass: class that remove
        ///     clientValid: function that call
        /// <param>
        RemoveNotValid: function(validator) {
            var $control = $('#' + validator.idControl);

            if (validator.cssClass) {
                $control.removeClass(validator.cssClass);
            }

            if (validator.clientValid) {
                validator.clientValid(validator.idControl);
            }

            if (validator.extraAlert != null) {
                if (validator.extraAlert == $.Validators.ExtraAlert.Asterix) {
                    $('#atx' + validator.idControl).remove();
                } else if (validator.extraAlert == $.Validators.ExtraAlert.ToolTip) {
                    $control.attr('title', '');
                } else {
                    $('#pop' + validator.idControl).remove();
                }
            }
        },
        /// <summary>Validate all control into group</summary>
        /// <param name="groupName">Name of validation group</param>
        ValidateControls: function(groupName) {
            var result = true;

            $.each($.Validators.GroupValidators[groupName], function(i) {
                var validator = $.Validators.GroupValidators[groupName][i];
                var isValid = true;

                switch (validator.type) {
                    case $.Validators.Types.Required:
                        {
                            isValid = $.Validators.Functions.ValidateRequired(validator.idControl);

                            if (!isValid) {
                                validator.error = 'Campo Obbligatorio';
                            }
                            break;
                        }
                    case $.Validators.Types.Length:
                        {
                            isValid = $.Validators.Functions.ValidateLength(validator.idControl, validator.min, validator.max);

                            if (!isValid) {
                                validator.error = 'Lunghezza del testo non valida (minimo: ' + validator.min + ', massimo : ' + validator.max + ')';
                            }
                            break;
                        }
                    case $.Validators.Types.Compare:
                        {
                            var cmpValue = '';
                            if (validator.value) {
                                cmpValue = validator.value;
                            } else {
                                cmpValue = $('#' + validator.cmpIDControl).val();
                            }
                            isValid = $.Validators.Functions.ValidateCompare(validator.idControl, cmpValue, validator.cmpOp);

                            if (!isValid) {
                                validator.error = 'Campo non Valido';
                            }
                            break;
                        }
                    case $.Validators.Types.Range:
                        {
                            isValid = $.Validators.Functions.ValidateRange(validator.idControl, validator.min, validator.max, validator.varType);

                            if (!isValid) {
                                validator.error = 'Campo non Valido (minimo: ' + validator.min + ', massimo: ' + validator.max + ')';
                            }
                            break;
                        }
                    case $.Validators.Types.RegularExpression:
                        {
                            isValid = $.Validators.Functions.ValidateRegex(validator.idControl, validator.regex);

                            if (!isValid) {
                                validator.error = 'Il valore non è valido';
                            }
                            break;
                        }
                }

                if (!isValid) {
                    $.Validators.Functions.AddNotValid(validator);
                } else {
                    $.Validators.Functions.RemoveNotValid(validator);
                }

                if (result) {
                    result = isValid;
                }
            });

            return result;
        }
    };

    jQuery.fn.extend({
        /// <summary>Create Validator</summary>
        /// <returns>jQuery element</returns>
        CreateValidator: function() {
            var $control = $(this);

            $control.first('onclick', function() {
                return $.Validators.Functions.ValidateControls($control.attr('id'));
            }, true);

            return $control;
        },
        /// <summary>Add control to validation list</summary>
        /// <param name="type">Type of validation</param>
        /// <param name="idControl">code of control that validate</param>
        /// <param name="attributes">
        ///     clientNotValid: function that call when data is not valid
        ///     clientValid: function that call when data is valid
        ///     cssClass: name of class for control, that contain not valid data
        ///     min: Start Range
        ///     max: End Range
        ///     regex: Regular Expression
        ///     value: data that compare
        ///     cmpIDControl: code of control that compare data
        ///     cmpOp: Compare Type
        ///     varType: Range Type
        ///     extraAlert: ExtraAlert Type
        ///     extraCss: Css for extra alert
        /// </param>
        /// <returns>jQuery element</returns>
        AddValidation: function(type, idControl, attributes) {
            var $control = $(this);
            $.Validators.Functions.AddValidator($control.attr('id'), type, idControl, attributes);

            return $control;
        },
        /// <summary>Remove control to validation list</summary>
        /// <param name="idControl">code of control</param>
        /// <returns>jQuery element</returns>
        RemoveValidation: function(idControl) {
            var $control = $(this);
            $.Validators.Functions.RemoveValidator(idControl);

            return $control;
        }
    });
})(jQuery);